package com.macro.mall.portal.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.github.pagehelper.PageHelper;
import com.macro.mall.common.api.CommonPage;
import com.macro.mall.common.api.CommonResult;
import com.macro.mall.mapper.*;
import com.macro.mall.model.*;
import com.macro.mall.portal.dao.DistributionOrderDao;
import com.macro.mall.portal.dao.PortalOrderDao;
import com.macro.mall.portal.dao.WithdrawalApplyDao;
import com.macro.mall.portal.domain.OmsOrderDetail;
import com.macro.mall.portal.service.OmsDistributionOrderService;
import com.macro.mall.portal.service.UmsMemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OmsDistributionOrderServiceImpl implements OmsDistributionOrderService {
    @Autowired
    private OmsDistributionOrderMapper omsDistributionOrderMapper;
    @Autowired
    private OmsOrderItemMapper orderItemMapper;
    @Autowired
    private OmsOrderMapper orderMapper;
    @Autowired
    private PortalOrderDao orderDao;
    @Autowired
    private UmsMemberService memberService;
    @Autowired
    private DistributionOrderDao distributionOrderDao;
    @Autowired
    private WithdrawalApplyDao withdrawalApplyDao;
    @Autowired
    private UmsWithdrawalApplyMapper withdrawalApplyMapper;
    @Autowired
    private UmsAdminMapper umsAdminMapper;

    @Override
    public int insertByOrderId(Long orderId) {
        if (orderId != null) {
            OmsOrderItemExample example = new OmsOrderItemExample();
            example.createCriteria().andOrderIdEqualTo(orderId).andStatusEqualTo(3);
            OmsOrder omsOrder = this.orderMapper.selectByPrimaryKey(orderId);
            UmsMember member = this.memberService.getById(omsOrder.getMemberId());
            if (member.getAgentId() != null) {
                List<OmsOrderItem> omsOrderItems = this.orderItemMapper.selectByExample(example);
                OmsDistributionOrder omsDistributionOrder = new OmsDistributionOrder();
                omsDistributionOrder.setCreateTime(new Date());
                omsDistributionOrder.setMemberId(omsOrder.getMemberId());
                omsDistributionOrder.setOrderId(omsOrder.getId());
                omsDistributionOrder.setOrderSn(omsOrder.getOrderSn());
                omsDistributionOrder.setStatus(OmsDistributionOrder.STATUS.FINISH.value());
                omsDistributionOrder.setStoreId(omsOrder.getUserStoreId());
                omsDistributionOrder.setStoreUserId(omsOrder.getUserId());
                omsDistributionOrder.setAgentId(member.getAgentId());//跟经纪人绑定
                BigDecimal commissionAmount = BigDecimal.ZERO;
                for (OmsOrderItem e : omsOrderItems) {
                    commissionAmount = commissionAmount.add(e.getCommissionAmount());
                }
                if (commissionAmount.compareTo(BigDecimal.ZERO) == 0) {
                    return 0;
                }
                omsDistributionOrder.setCommissionAmount(commissionAmount);
                this.omsDistributionOrderMapper.insert(omsDistributionOrder);
            }
        }
        return 0;
    }

    @Override
    public Map<String, Object> getList(Integer pageNum, Integer pageSize, Date start, Date end) {
        Map<String, Object> result = new HashMap<>();
        CommonPage<OmsOrderDetail> resultPage = new CommonPage<>();
        UmsMember member = memberService.getCurrentMember();
        PageHelper.startPage(pageNum, pageSize);
        OmsOrderExample orderExample = new OmsOrderExample();
        OmsOrderExample.Criteria criteria = orderExample.createCriteria();
        criteria.andDeleteStatusEqualTo(0)
                .andAgentIdEqualTo(member.getId())
                .andStatusEqualTo(3);
        if (start != null && end != null) {
            criteria.andReceiveTimeBetween(start, end);
        } else if (start != null && end == null) {
            criteria.andReceiveTimeGreaterThanOrEqualTo(start);
        } else if (start == null && end != null) {
            criteria.andReceiveTimeLessThan(end);
        }
        orderExample.setOrderByClause("create_time desc");
        List<OmsOrder> orderList = this.orderMapper.selectByExample(orderExample);
        CommonPage<OmsOrder> orderPage = CommonPage.restPage(orderList);
        //设置分页信息
        resultPage.setPageNum(orderPage.getPageNum());
        resultPage.setPageSize(orderPage.getPageSize());
        resultPage.setTotal(orderPage.getTotal());
        resultPage.setTotalPage(orderPage.getTotalPage());
        if (CollUtil.isEmpty(orderList)) {
            result.put("totalAmount",BigDecimal.ZERO);
            result.put("allCommission",BigDecimal.ZERO);
            result.put("pageInfo", resultPage);
            return result;
        }
        //设置数据信息
        List<Long> orderIds = orderList.stream().map(OmsOrder::getId).collect(Collectors.toList());
        OmsOrderItemExample orderItemExample = new OmsOrderItemExample();
        orderItemExample.createCriteria().andOrderIdIn(orderIds);
//                .andStatusEqualTo(OmsOrderItem.STATUS.FINISH.value());
        List<OmsOrderItem> orderItemList = orderItemMapper.selectByExample(orderItemExample);
        List<OmsOrderDetail> orderDetailList = new ArrayList<>();
        for (OmsOrder omsOrder : orderList) {
            OmsOrderDetail orderDetail = new OmsOrderDetail();
            BeanUtil.copyProperties(omsOrder, orderDetail);
            List<OmsOrderItem> relatedItemList = orderItemList.stream().filter(item -> item.getOrderId().equals(orderDetail.getId())).collect(Collectors.toList());
            //计算总数量和总佣金
            int sum = 0;
            BigDecimal totalCommission = BigDecimal.ZERO;
            if(!CollectionUtils.isEmpty(orderDetailList)){
                sum = relatedItemList.stream().mapToInt(e -> e.getProductQuantity()).sum();
            }
            orderDetail.setTotalQuantity(sum);

            if(!CollectionUtils.isEmpty(relatedItemList)){
                for (OmsOrderItem omsOrderItem : relatedItemList){
                    BigDecimal commissionAmount = omsOrderItem.getCommissionAmount();
                    totalCommission = totalCommission.add(commissionAmount);
                }
            }
            orderDetail.setTotalCommission(totalCommission);
            orderDetail.setOrderItemList(relatedItemList);
            orderDetailList.add(orderDetail);
        }
        resultPage.setList(orderDetailList);
        result.put("pageInfo", resultPage);
        result.put("totalAmount", this.getTotalAmount(member.getId(), start, end));
        result.put("allCommission", this.orderDao.getAllCommissionByItem(member.getId(), start, end));
        return result;
    }

    @Override
    public BigDecimal getAllCommission(Date start, Date end) {
        UmsMember member = memberService.getCurrentMember();
        return this.orderDao.getAllCommissionByItem(member.getId(), start, end);
    }

    @Override
    public BigDecimal getTotalAmount(Long agentId, Date start, Date end) {
        return this.orderDao.getTotalAmount(agentId, start, end);
    }

    @Override
    public Map<String, BigDecimal> getWithdrawalAmount() {
        UmsMember currentMember = this.memberService.getCurrentMember();
        Map<String, BigDecimal> result = new HashMap<>();
        //用户所有佣金总金额
        BigDecimal allCommission = BigDecimal.ZERO;
//        BigDecimal allCommissionResult = this.distributionOrderDao.getTotalCommission(currentMember.getId(), null);
        BigDecimal allCommissionResult = this.orderDao.getAllCommissionByItem(currentMember.getId(),null,null);
        if (allCommissionResult != null) {
            allCommission = allCommissionResult;
        }
        //用户已结算的佣金总额
        BigDecimal totalCommission = BigDecimal.ZERO;
        BigDecimal totalCommissionResult = this.getTotalCommission(currentMember.getId());
        if (totalCommissionResult != null) {
            totalCommission = totalCommissionResult;
        }
        //用户已经提现的总金额
        BigDecimal hasWithdrawalCommission = BigDecimal.ZERO;
        BigDecimal hasWithdrawalCommissionResult = this.getHasWithdrawalCommission(currentMember.getId(), null, null);
        if (hasWithdrawalCommissionResult != null) {
            hasWithdrawalCommission = hasWithdrawalCommissionResult;
        }

        result.put("disable", allCommission.subtract(totalCommission));//不可提现的金额
        result.put("enable", totalCommission.subtract(hasWithdrawalCommission));//可提现的金额


        return result;
    }

    @Override
    public BigDecimal getTotalCommission(Long agentId) {
        return this.distributionOrderDao.getTotalCommission(agentId, 6);
    }

    @Override
    public BigDecimal getHasWithdrawalCommission(Long agentId, Date start, Date end) {
        return this.withdrawalApplyDao.getHasWithdrawalCommission(agentId, start, end);
    }

    @Override
    public Map<String, Object> withdrawalRecord(Integer pageNum, Integer pageSize, Date start) {//结束时间去掉了
        UmsMember currentMember = this.memberService.getCurrentMember();
        Map<String, Object> result = new HashMap<>();
        PageHelper.startPage(pageNum, pageSize);
        UmsWithdrawalApplyExample example = new UmsWithdrawalApplyExample();
        UmsWithdrawalApplyExample.Criteria criteria =
                example.createCriteria()
                        .andMemberIdEqualTo(currentMember.getId());
        //结束时间设置为今天
        Date end = new Date();
        if (start != null && end != null) {
            criteria.andCreateTimeBetween(start, end);
        } else if (start != null && end == null) {
            criteria.andCreateTimeGreaterThanOrEqualTo(start);
        } else if (start == null && end != null) {
            criteria.andCreateTimeLessThan(end);

        }
        example.setOrderByClause("id desc");
        List<UmsWithdrawalApply> list = this.withdrawalApplyMapper.selectByExample(example);
        CommonPage<UmsWithdrawalApply> pageInfo = CommonPage.restPage(list);
        BigDecimal hasWithdrawalCommission = this.getHasWithdrawalCommission(currentMember.getId(), start, end);
        if (hasWithdrawalCommission == null) {
            hasWithdrawalCommission = BigDecimal.ZERO;
        }
        result.put("pageInfo", pageInfo);
        result.put("hasWithdrawalCommission", hasWithdrawalCommission);
        return result;
    }

    @Override
    public CommonResult<Integer> withdrawalApply(BigDecimal amount) {
        CommonResult result;
        UmsMember currentMember = this.memberService.getCurrentMember();
        //用户可提现的佣金总额
        BigDecimal totalCommission = this.getTotalCommission(currentMember.getId());
        //用户已经提现的总金额
        BigDecimal hasWithdrawalCommission = this.getHasWithdrawalCommission(currentMember.getId(), null, null);
        if (hasWithdrawalCommission == null) {
            hasWithdrawalCommission = BigDecimal.ZERO;
        }
        if(totalCommission!=null){
            if ((totalCommission.subtract(hasWithdrawalCommission)).compareTo(amount) >= 0) {
                UmsAdmin umsAdmin = this.umsAdminMapper.selectByPrimaryKey(currentMember.getStoreUserId());
                UmsWithdrawalApply apply = new UmsWithdrawalApply();
                apply.setAdminId(currentMember.getStoreUserId());
                apply.setAdminUserName(umsAdmin.getUsername());
                apply.setStoreId(currentMember.getStoreId());
                apply.setAmount(amount);
                apply.setCreateTime(new Date());
                apply.setMemberId(currentMember.getId());
                apply.setStatus(0);
                apply.setType(0);
                int i = this.withdrawalApplyMapper.insertSelective(apply);
                if (i > 0) {
                    return CommonResult.success(i);
                } else {
                    return CommonResult.failed("申请提现失败，请稍后再试");
                }
            } else {
                result = CommonResult.failed("申请提现失败，提现金额不能大于允许提现金额");
            }
        }else{
            result = CommonResult.failed("佣金不能为空");
        }
        return result;
    }
}
